using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using ComponentSystem;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Audio;
using UnityActionSystem;
using ZYFramework.ObjectPool;

namespace ZYFramework.AudioSystem
{
    /// <summary>
    /// 音频播放控制组件
    /// </summary>
    public class Com_AudioPlayController : ComponentWithId
    {
        /// <summary>
        /// 当前播放的音效信息
        /// </summary>
        private struct PlayingAudioInfo
        {
            public string AudioName;
            public GameObject AudioSourceObj;
            public AudioType AudioType;
            public bool IsPlaying;
        }

        /// <summary>
        /// 资源管理组件
        /// </summary>
        private Com_AudioResourceManager _resourceManager;

        /// <summary>
        /// 对象池组件
        /// </summary>
        private Com_AudioSourcePool _sourcePool;

        /// <summary>
        /// 3D更新器组件
        /// </summary>
        private Com_Audio3DUpdater _3DUpdater;

        /// <summary>
        /// 全局控制组件
        /// </summary>
        private Com_AudioGlobalControl _globalControl;

        /// <summary>
        /// 框架配置
        /// </summary>
        private AudioConfig _config;

        /// <summary>
        /// 当前播放的音效字典（AudioName -> PlayingAudioInfo）
        /// </summary>
        private readonly Dictionary<string, PlayingAudioInfo> _playingAudios = new Dictionary<string, PlayingAudioInfo>();

        /// <summary>
        /// 当前播放的BGM AudioSource（BGM唯一播放）
        /// </summary>
        private GameObject _currentBGMAudioSource;

        /// <summary>
        /// 取消令牌源
        /// </summary>
        private CancellationTokenSource _cancellationTokenSource;

        /// <summary>
        /// EventBusEntity引用
        /// </summary>
        private EventBusEntity _eventBus;

        protected override void Awake()
        {
            base.Awake();
            _cancellationTokenSource = new CancellationTokenSource();
        }

        protected override void Start()
        {
            base.Start();
        }

        /// <summary>
        /// 初始化播放控制器
        /// </summary>
        /// <param name="resourceManager">资源管理组件</param>
        /// <param name="sourcePool">对象池组件</param>
        /// <param name="updater3D">3D更新器组件</param>
        /// <param name="globalControl">全局控制组件</param>
        /// <param name="config">框架配置</param>
        public void Initialize(
            Com_AudioResourceManager resourceManager,
            Com_AudioSourcePool sourcePool,
            Com_Audio3DUpdater updater3D,
            Com_AudioGlobalControl globalControl,
            AudioConfig config)
        {
            this._resourceManager = resourceManager;
            this._sourcePool = sourcePool;
            this._3DUpdater = updater3D;
            this._globalControl = globalControl;
            this._config = config;

            // 订阅音频事件（如果EventBusEntity可用）
            SubscribeAudioEvents();
        }

        /// <summary>
        /// 订阅音频事件
        /// </summary>
        private void SubscribeAudioEvents()
        {
            try
            {
                // 尝试获取EventBusEntity实例
                // 注意：EventBusEntity需要通过其他方式获取，这里先假设可以通过某种方式获取
                // 在实际使用时，需要确保EventBusEntity已初始化
                _eventBus = GetEventBusEntity();

                if (_eventBus != null)
                {
                    _eventBus.Subscribe<PlaySFXEventData>(AudioEventIds.PlaySFX, OnPlaySFXEvent);
                    _eventBus.Subscribe<Play3DSFXEventData>(AudioEventIds.Play3DSFX, OnPlay3DSFXEvent);
                    _eventBus.Subscribe<PlayBGMEventData>(AudioEventIds.PlayBGM, OnPlayBGMEvent);
                    _eventBus.Subscribe<StopAudioEventData>(AudioEventIds.StopAudio, OnStopAudioEvent);
                    _eventBus.Subscribe<StopAllAudioEventData>(AudioEventIds.StopAllAudio, OnStopAllAudioEvent);
                }
            }
            catch (Exception e)
            {
                Debug.LogWarning($"[AudioPlayController] 订阅音频事件失败: {e.Message}");
            }
        }

        /// <summary>
        /// 获取EventBusEntity实例
        /// </summary>
        /// <returns>EventBusEntity实例</returns>
        /// <remarks>
        /// 注意：EventBusEntity需要通过Initialization方法初始化后才能使用
        /// 如果EventBusEntity未初始化，事件触发方式将不可用，但直接调用方式仍然可用
        /// 如果需要使用事件触发方式，请确保EventBusEntity已正确初始化
        /// </remarks>
        private EventBusEntity GetEventBusEntity()
        {
            // 尝试通过反射获取EventBusEntity的静态实例（如果可用）
            // 注意：这需要EventBusEntity已通过Initialization方法初始化
            try
            {
                var eventBusType = typeof(UnityActionSystem.EventBusEntity);
                var instanceField = eventBusType.GetField("_instance", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
                if (instanceField != null)
                {
                    var instance = instanceField.GetValue(null) as UnityActionSystem.EventBusEntity;
                    return instance;
                }
            }
            catch
            {
                // 反射失败，返回null
            }

            // 如果反射失败或EventBusEntity未初始化，返回null
            // 框架仍可通过直接调用方式工作
            return null;
        }

        #region 事件处理

        /// <summary>
        /// 处理播放2D音效事件
        /// </summary>
        private void OnPlaySFXEvent(PlaySFXEventData eventData)
        {
            PlaySFX2DAsync(eventData.AudioName, eventData.Params, _cancellationTokenSource.Token).Forget();
        }

        /// <summary>
        /// 处理播放3D音效事件
        /// </summary>
        private void OnPlay3DSFXEvent(Play3DSFXEventData eventData)
        {
            PlaySFX3DAsync(eventData.AudioName, eventData.BindTransform, eventData.Params, _cancellationTokenSource.Token).Forget();
        }

        /// <summary>
        /// 处理播放BGM事件
        /// </summary>
        private void OnPlayBGMEvent(PlayBGMEventData eventData)
        {
            PlayBGMAsync(eventData.AudioName, eventData.Params, _cancellationTokenSource.Token).Forget();
        }

        /// <summary>
        /// 处理停止音效事件
        /// </summary>
        private void OnStopAudioEvent(StopAudioEventData eventData)
        {
            StopAudio(eventData.AudioName, eventData.AudioType);
        }

        /// <summary>
        /// 处理停止所有音效事件
        /// </summary>
        private void OnStopAllAudioEvent(StopAllAudioEventData eventData)
        {
            StopAllAudio(eventData.AudioType);
        }

        #endregion

        #region 直接调用方式（公共API）

        /// <summary>
        /// 播放2D音效（简化版，直接调用）
        /// </summary>
        /// <param name="audioName">音效名称</param>
        /// <param name="param">播放参数（可选）</param>
        /// <param name="ct">取消令牌</param>
        public async UniTask PlaySFX2DAsync(string audioName, AudioPlayParams? param = null, CancellationToken ct = default)
        {
            if (string.IsNullOrEmpty(audioName))
            {
                Debug.LogError("[AudioPlayController] 音效名称为空");
                return;
            }

            try
            {
                // 加载音频资源
                AudioClip audioClip = await _resourceManager.GetAudioClipAsync(audioName, AudioType.SFX_2D, ct);
                if (audioClip == null)
                {
                    return;
                }

                // 获取播放参数
                AudioPlayParams playParams = param ?? AudioPlayParams.Default;

                // 获取空闲AudioSource
                GameObject audioSourceObj = _sourcePool.GetFreeAudioSource2D();
                if (audioSourceObj == null)
                {
                    Debug.LogWarning($"[AudioPlayController] 2D对象池已满，无法播放音效: {audioName}");
                    return;
                }

                // 配置AudioSource
                AudioSource audioSource = audioSourceObj.GetComponent<AudioSource>();
                ConfigureAudioSource(audioSource, audioClip, playParams, AudioType.SFX_2D, false);

                // 播放音效
                audioSource.Play();

                // 记录播放信息
                string playKey = GetPlayKey(audioName, AudioType.SFX_2D);
                _playingAudios[playKey] = new PlayingAudioInfo
                {
                    AudioName = audioName,
                    AudioSourceObj = audioSourceObj,
                    AudioType = AudioType.SFX_2D,
                    IsPlaying = true
                };

                // 监听播放完成并自动回收
                WaitForPlayCompleteAsync(audioSourceObj, audioName, AudioType.SFX_2D, ct).Forget();
            }
            catch (OperationCanceledException)
            {
                // 取消操作，不做处理
            }
            catch (Exception e)
            {
                Debug.LogError($"[AudioPlayController] 播放2D音效异常: {audioName}, 错误: {e.Message}");
            }
        }

        /// <summary>
        /// 播放3D音效（绑定Transform）
        /// </summary>
        /// <param name="audioName">音效名称</param>
        /// <param name="bindTransform">绑定的Transform</param>
        /// <param name="param">播放参数（可选）</param>
        /// <param name="ct">取消令牌</param>
        public async UniTask PlaySFX3DAsync(string audioName, Transform bindTransform, AudioPlayParams? param = null, CancellationToken ct = default)
        {
            if (string.IsNullOrEmpty(audioName))
            {
                Debug.LogError("[AudioPlayController] 音效名称为空");
                return;
            }

            if (bindTransform == null)
            {
                Debug.LogError("[AudioPlayController] 绑定的Transform为空");
                return;
            }

            try
            {
                // 加载音频资源
                AudioClip audioClip = await _resourceManager.GetAudioClipAsync(audioName, AudioType.SFX_3D, ct);
                if (audioClip == null)
                {
                    return;
                }

                // 获取播放参数
                AudioPlayParams playParams = param ?? AudioPlayParams.Create3D();

                // 获取空闲AudioSource
                GameObject audioSourceObj = _sourcePool.GetFreeAudioSource3D();
                if (audioSourceObj == null)
                {
                    Debug.LogWarning($"[AudioPlayController] 3D对象池已满，无法播放音效: {audioName}");
                    return;
                }

                // 配置AudioSource
                AudioSource audioSource = audioSourceObj.GetComponent<AudioSource>();
                ConfigureAudioSource(audioSource, audioClip, playParams, AudioType.SFX_3D, true);

                // 设置位置
                audioSourceObj.transform.position = bindTransform.position;

                // 添加到3D更新器
                _3DUpdater.Add3DBinding(audioSourceObj, bindTransform);

                // 播放音效
                audioSource.Play();

                // 记录播放信息
                string playKey = GetPlayKey(audioName, AudioType.SFX_3D);
                _playingAudios[playKey] = new PlayingAudioInfo
                {
                    AudioName = audioName,
                    AudioSourceObj = audioSourceObj,
                    AudioType = AudioType.SFX_3D,
                    IsPlaying = true
                };

                // 监听播放完成并自动回收
                WaitForPlayCompleteAsync(audioSourceObj, audioName, AudioType.SFX_3D, ct).Forget();
            }
            catch (OperationCanceledException)
            {
                // 取消操作，不做处理
            }
            catch (Exception e)
            {
                if (Application.isPlaying)
                {
                    Debug.LogError($"[AudioPlayController] 播放3D音效异常: {audioName}, 错误: {e.Message}");
                }
            }
        }

        /// <summary>
        /// 播放BGM（唯一播放，淡入淡出切换）
        /// </summary>
        /// <param name="audioName">BGM名称</param>
        /// <param name="param">播放参数（可选）</param>
        /// <param name="ct">取消令牌</param>
        public async UniTask PlayBGMAsync(string audioName, AudioPlayParams? param = null, CancellationToken ct = default)
        {
            if (string.IsNullOrEmpty(audioName))
            {
                Debug.LogError("[AudioPlayController] BGM名称为空");
                return;
            }

            try
            {
                // 如果已有BGM正在播放，先淡出
                if (_currentBGMAudioSource != null)
                {
                    AudioSource currentAudioSource = _currentBGMAudioSource.GetComponent<AudioSource>();
                    if (currentAudioSource != null)
                    {
                        await _globalControl.FadeOutBGMAsync(currentAudioSource, _config.BGMFadeTime, ct);
                    }
                    StopAudioInternal(_currentBGMAudioSource, AudioType.BGM);
                    _currentBGMAudioSource = null;
                }

                // 加载BGM资源
                AudioClip audioClip = await _resourceManager.GetAudioClipAsync(audioName, AudioType.BGM, ct);
                if (audioClip == null)
                {
                    // 输出详细的错误信息
                    string resourcePath = (_config?.BGMPathPrefix ?? "") + audioName;
                    string packageName = _config?.ResourcePackageName ?? "未配置";
                    Debug.LogError($"[AudioPlayController] 加载BGM失败: {audioName}\n" +
                                   $"  资源路径: {resourcePath}\n" +
                                   $"  资源包名: {packageName}\n" +
                                   $"  音频类型: BGM\n" +
                                   $"  请检查：1) 资源路径是否正确 2) 资源包是否正确加载 3) 音频文件是否存在");
                    return;
                }

                // 获取播放参数
                AudioPlayParams playParams = param ?? AudioPlayParams.Default;
                playParams.Loop = true; // BGM默认循环

                // 获取空闲AudioSource（BGM使用2D池）
                GameObject audioSourceObj = _sourcePool.GetFreeAudioSource2D();
                if (audioSourceObj == null)
                {
                    Debug.LogWarning($"[AudioPlayController] 2D对象池已满，无法播放BGM: {audioName}");
                    return;
                }

                // 配置AudioSource
                AudioSource audioSource = audioSourceObj.GetComponent<AudioSource>();
                ConfigureAudioSource(audioSource, audioClip, playParams, AudioType.BGM, false);

                // 保存目标音量（在设置volume为0之前获取）
                float targetVolume = playParams.Volume;

                // 播放BGM（先静音，然后淡入）
                audioSource.volume = 0f; // 初始音量为0
                audioSource.Play();

                // 记录当前BGM
                _currentBGMAudioSource = audioSourceObj;

                // 淡入BGM（传入目标音量）
                await _globalControl.FadeInBGMAsync(audioSource, _config.BGMFadeTime, targetVolume, ct);
            }
            catch (OperationCanceledException)
            {
                // 取消操作，不做处理
            }
            catch (Exception e)
            {
                if (Application.isPlaying)
                {
                    Debug.LogError($"[AudioPlayController] 播放BGM异常: {audioName}, 错误: {e.Message}");
                }
            }
        }

        /// <summary>
        /// 停止指定音效
        /// </summary>
        /// <param name="audioName">音效名称</param>
        /// <param name="audioType">音频类型</param>
        public void StopAudio(string audioName, AudioType audioType)
        {
            if (string.IsNullOrEmpty(audioName))
            {
                return;
            }

            string playKey = GetPlayKey(audioName, audioType);
            if (_playingAudios.TryGetValue(playKey, out PlayingAudioInfo info))
            {
                StopAudioInternal(info.AudioSourceObj, audioType);
                _playingAudios.Remove(playKey);
            }
        }

        /// <summary>
        /// 停止所有音效（按类型）
        /// </summary>
        /// <param name="audioType">音频类型（null表示停止所有类型）</param>
        public void StopAllAudio(AudioType? audioType = null)
        {
            List<string> keysToRemove = new List<string>();

            foreach (var kvp in _playingAudios)
            {
                if (audioType == null || kvp.Value.AudioType == audioType)
                {
                    StopAudioInternal(kvp.Value.AudioSourceObj, kvp.Value.AudioType);
                    keysToRemove.Add(kvp.Key);
                }
            }

            foreach (var key in keysToRemove)
            {
                _playingAudios.Remove(key);
            }

            // 如果是BGM，也要停止
            if (audioType == null || audioType == AudioType.BGM)
            {
                if (_currentBGMAudioSource != null)
                {
                    StopAudioInternal(_currentBGMAudioSource, AudioType.BGM);
                    _currentBGMAudioSource = null;
                }
            }
        }

        #endregion

        #region 内部辅助方法

        /// <summary>
        /// 配置AudioSource参数
        /// </summary>
        private void ConfigureAudioSource(AudioSource audioSource, AudioClip clip, AudioPlayParams param, AudioType audioType, bool is3D)
        {
            audioSource.clip = clip;
            audioSource.volume = param.Volume;
            audioSource.pitch = param.Pitch;
            audioSource.loop = param.Loop;
            audioSource.spatialBlend = param.SpatialBlend;

            if (is3D)
            {
                audioSource.minDistance = param.MinDistance;
                audioSource.maxDistance = param.MaxDistance;
            }

            // 设置AudioMixerGroup
            if (_config != null && _config.AudioMixer != null)
            {
                AudioMixerGroup targetGroup = null;
                string groupName = "";

                switch (audioType)
                {
                    case AudioType.BGM:
                        groupName = "BGM_Group";
                        break;
                    case AudioType.SFX_2D:
                        groupName = "SFX_2D_Group";
                        break;
                    case AudioType.SFX_3D:
                        groupName = "SFX_3D_Group";
                        break;
                }

                if (!string.IsNullOrEmpty(groupName))
                {
                    var matchingGroups = _config.AudioMixer.FindMatchingGroups(groupName);
                    if (matchingGroups != null && matchingGroups.Length > 0)
                    {
                        targetGroup = matchingGroups[0];
                        audioSource.outputAudioMixerGroup = targetGroup;
                    }
                    else
                    {
                        Debug.LogWarning($"[AudioPlayController] 未找到AudioMixerGroup: {groupName}，音频将输出到Master组");
                    }
                }
            }
            else
            {
                Debug.LogWarning("[AudioPlayController] AudioMixer未配置，音频将输出到默认组");
            }
        }

        /// <summary>
        /// 获取播放键（用于标识同一个音效的多个播放实例）
        /// </summary>
        private string GetPlayKey(string audioName, AudioType audioType)
        {
            return $"{audioType}_{audioName}_{Time.time}";
        }

        /// <summary>
        /// 等待播放完成并自动回收
        /// </summary>
        private async UniTaskVoid WaitForPlayCompleteAsync(GameObject audioSourceObj, string audioName, AudioType audioType, CancellationToken ct)
        {
            if (audioSourceObj == null)
            {
                return;
            }

            AudioSource audioSource = audioSourceObj.GetComponent<AudioSource>();
            if (audioSource == null)
            {
                return;
            }

            try
            {
                // 等待播放开始
                while (!audioSource.isPlaying && !ct.IsCancellationRequested)
                {
                    await UniTask.Yield(PlayerLoopTiming.Update, ct);
                }

                // 如果是循环播放，不自动回收
                if (audioSource.loop)
                {
                    return;
                }

                // 等待播放完成
                while (audioSource.isPlaying && !ct.IsCancellationRequested)
                {
                    await UniTask.Yield(PlayerLoopTiming.Update, ct);
                }

                // 播放完成，自动回收
                if (!ct.IsCancellationRequested)
                {
                    StopAudioInternal(audioSourceObj, audioType);

                    // 从播放列表中移除
                    string playKeyToRemove = null;
                    foreach (var kvp in _playingAudios)
                    {
                        if (kvp.Value.AudioSourceObj == audioSourceObj)
                        {
                            playKeyToRemove = kvp.Key;
                            break;
                        }
                    }

                    if (playKeyToRemove != null)
                    {
                        _playingAudios.Remove(playKeyToRemove);
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // 取消操作，不做处理
            }
            catch (Exception e)
            {
                // 编辑器停止运行时不需要记录错误
                if (Application.isPlaying)
                {
                    Debug.LogError($"[AudioPlayController] 等待播放完成异常: {audioName}, 错误: {e.Message}");
                }
            }
        }

        /// <summary>
        /// 停止音效内部方法
        /// </summary>
        private void StopAudioInternal(GameObject audioSourceObj, AudioType audioType)
        {
            if (audioSourceObj == null)
            {
                return;
            }

            AudioSource audioSource = audioSourceObj.GetComponent<AudioSource>();
            if (audioSource != null)
            {
                audioSource.Stop();
            }

            // 如果是3D音效，从3D更新器中移除
            if (audioType == AudioType.SFX_3D)
            {
                _3DUpdater.Remove3DBinding(audioSourceObj);
            }

            // 回收到对象池
            if (audioType == AudioType.SFX_2D || audioType == AudioType.BGM)
            {
                _sourcePool.RecycleAudioSource2D(audioSourceObj);
            }
            else if (audioType == AudioType.SFX_3D)
            {
                _sourcePool.RecycleAudioSource3D(audioSourceObj);
            }
        }

        #endregion

        /// <summary>
        /// 获取当前播放的音效列表（调试用）
        /// </summary>
        public List<string> GetPlayingAudioList()
        {
            List<string> list = new List<string>();
            foreach (var kvp in _playingAudios)
            {
                if (kvp.Value.IsPlaying)
                {
                    list.Add($"{kvp.Value.AudioName}({kvp.Value.AudioType})");
                }
            }

            if (_currentBGMAudioSource != null)
            {
                list.Add("BGM(正在播放)");
            }

            return list;
        }

        public override void Dispose()
        {
            base.Dispose();
            _cancellationTokenSource?.Cancel();
            _cancellationTokenSource?.Dispose();

            // 取消订阅事件
            if (_eventBus != null)
            {
                try
                {
                    _eventBus.Unsubscribe<PlaySFXEventData>(AudioEventIds.PlaySFX, OnPlaySFXEvent);
                    _eventBus.Unsubscribe<Play3DSFXEventData>(AudioEventIds.Play3DSFX, OnPlay3DSFXEvent);
                    _eventBus.Unsubscribe<PlayBGMEventData>(AudioEventIds.PlayBGM, OnPlayBGMEvent);
                    _eventBus.Unsubscribe<StopAudioEventData>(AudioEventIds.StopAudio, OnStopAudioEvent);
                    _eventBus.Unsubscribe<StopAllAudioEventData>(AudioEventIds.StopAllAudio, OnStopAllAudioEvent);
                }
                catch (Exception e)
                {
                    Debug.LogWarning($"[AudioPlayController] 取消订阅事件失败: {e.Message}");
                }
            }

            // 停止所有音效
            StopAllAudio();
        }
    }
}
